home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / yacc.arc / Y1.C < prev    next >
Text File  |  1985-09-04  |  17KB  |  675 lines

  1.  
  2. #include "c:dextern"                                                                                                  
  3.  
  4.  
  5.     /* variables used locally */
  6.  
  7.     /* lookahead computations */
  8.  
  9. int tbitset;  /* size of lookahead sets */
  10. struct looksets lkst [ LSETSIZE ];
  11. int nlset = 0; /* next lookahead set index */
  12. int nolook = 0; /* flag to suppress lookahead computations */
  13. struct looksets clset;  /* temporary storage for lookahead computations */
  14.  
  15.     /* working set computations */
  16.  
  17. struct wset wsets[ WSETSIZE ];
  18. struct wset *cwp;
  19.  
  20.     /* state information */
  21.  
  22. int nstate = 0;        /* number of states */
  23. struct item *pstate[NSTATES+2];    /* pointers to the descriptions of the states */
  24. int tystate[NSTATES];    /* contains type information about the states */
  25. int indgo[NSTATES];        /* index to the stored goto table */
  26. int tstates[ NTERMS ]; /* states generated by terminal gotos */
  27. int ntstates[ NNONTERM ]; /* states generated by nonterminal gotos */
  28. int mstates[ NSTATES ]; /* chain of overflows of term/nonterm generation lists  */
  29.  
  30.     /* storage for the actions in the parser */
  31.  
  32. int amem[ACTSIZE];    /* action table storage */
  33. int *memp = amem;    /* next free action table position */
  34.  
  35.     /* other storage areas */
  36.  
  37. int temp1[TEMPSIZE]; /* temporary storage, indexed by terms + ntokens or states */
  38. int lineno= 1; /* current input line number */
  39. int fatfl = 1;      /* if on, error is fatal */
  40. int nerrors = 0;    /* number of errors */
  41.  
  42.     /* storage for information about the nonterminals */
  43.  
  44. int **pres[NNONTERM+2];  /* vector of pointers to productions yielding each nonterminal */
  45. struct looksets *pfirst[NNONTERM+2];  /* vector of pointers to first sets for each nonterminal */
  46. int pempty[NNONTERM+1];  /* vector of nonterminals nontrivially deriving e */
  47.  
  48. main(argc,argv) int argc; char *argv[]; {
  49.  
  50.     setup(argc,argv); /* initialize and read productions */
  51.     tbitset = NWORDS(ntokens);
  52.     cpres(); /* make table of which productions yield a given nonterminal */
  53.     cempty(); /* make a table of which nonterminals can match the empty string */
  54.     cpfir(); /* make a table of firsts of nonterminals */
  55.     stagen(); /* generate the states */
  56.     output();  /* write the states and the tables */
  57.     go2out();
  58.     hideprod();
  59.     summary();
  60.     callopt();
  61.     others();
  62.     exit(0);
  63.     }
  64.  
  65. others(){ /* put out other arrays, copy the parsers */
  66.     register c, i, j;
  67.  
  68.     finput = fopen( PARSER, "r" );
  69.     if( finput == NULL ) error( "cannot find parser %s", PARSER );
  70.  
  71.     warray( "yyr1", levprd, nprod );
  72.  
  73.     aryfil( temp1, nprod, 0 );
  74.     PLOOP(1,i)temp1[i] = prdptr[i+1]-prdptr[i]-2;
  75.     warray( "yyr2", temp1, nprod );
  76.  
  77.     aryfil( temp1, nstate, -1000 );
  78.     TLOOP(i){
  79.         for( j=tstates[i]; j!=0; j=mstates[j] ){
  80.             temp1[j] = tokset[i].value;
  81.             }
  82.         }
  83.     NTLOOP(i){
  84.         for( j=ntstates[i]; j!=0; j=mstates[j] ){
  85.             temp1[j] = -i;
  86.             }
  87.         }
  88.     warray( "yychk", temp1, nstate );
  89.  
  90.     warray( "yydef", defact, nstate );
  91.  
  92.     /* copy parser text */
  93.  
  94.     while( (c=getc(finput) ) != EOF ){
  95.         if( c == '$' ){
  96.             if( (c=getc(finput)) != 'A' ) putc( '$', ftable );
  97.             else { /* copy actions */
  98.                 faction = fopen( ACTNAME, "r" );
  99.                 if( faction == NULL ) error( "cannot reopen action tempfile" );
  100.                 while( (c=getc(faction) ) != EOF ) putc( c, ftable );
  101.                 fclose(faction);
  102.                 ZAPFILE(ACTNAME);
  103.                 c = getc(finput);
  104.                 }
  105.             }
  106.         putc( c, ftable );
  107.         }
  108.  
  109.     fclose( ftable );
  110.     }
  111.  
  112. char *chcopy( p, q )  char *p, *q; {
  113.     /* copies string q into p, returning next free char ptr */
  114.     while( *p = *q++ ) ++p;
  115.     return( p );
  116.     }
  117.  
  118. #define ISIZE 400
  119. char *writem(pp) int *pp; { /* creates output string for item pointed to by pp */
  120.     int i,*p;
  121.     static char sarr[ISIZE];
  122.     char *q;
  123.  
  124.     for( p=pp; *p>0 ; ++p ) ;
  125.     p = prdptr[-*p];
  126.     q = chcopy( sarr, nontrst[*p-NTBASE].name );
  127.     q = chcopy( q, " : " );
  128.  
  129.     for(;;){
  130.         *q++ = ++p==pp ? '_' : ' ';
  131.         *q = '\0';
  132.         if((i = *p) <= 0) break;
  133.         q = chcopy( q, symnam(i) );
  134.         if( q> &sarr[ISIZE-30] ) error( "item too big" );
  135.         }
  136.  
  137.     if( (i = *pp) < 0 ){ /* an item calling for a reduction */
  138.         q = chcopy( q, "    (" );
  139.         sprintf( q, "%d)", -i );
  140.         }
  141.  
  142.     return( sarr );
  143.     }
  144.  
  145. char *symnam(i){ /* return a pointer to the name of symbol i */
  146.     char *cp;
  147.  
  148.     cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : tokset[i].name ;
  149.     if( *cp == ' ' ) ++cp;
  150.     return( cp );
  151.     }
  152.  
  153. struct wset *zzcwp = wsets;
  154. int zzgoent = 0;
  155. int zzgobest = 0;
  156. int zzacent = 0;
  157. int zzexcp = 0;
  158. int zzclose = 0;
  159. int zzsrconf = 0;
  160. int * zzmemsz = mem0;
  161. int zzrrconf = 0;
  162.  
  163. summary(){ /* output the summary on the tty */
  164.  
  165.     if( foutput!=NULL ){
  166.         fprintf( foutput, "\n%d/%d terminals, %d/%d nonterminals\n", ntokens, NTERMS,
  167.                 nnonter, NNONTERM );
  168.         fprintf( foutput, "%d/%d grammar rules, %d/%d states\n", nprod, NPROD, nstate, NSTATES );
  169.         fprintf( foutput, "%d shift/reduce, %d reduce/reduce conflicts reported\n", zzsrconf, zzrrconf );
  170.         fprintf( foutput, "%d/%d working sets used\n", zzcwp-wsets,  WSETSIZE );
  171.         fprintf( foutput, "memory: states,etc. %d/%d, parser %d/%d\n", zzmemsz-mem0, MEMSIZE,
  172.                 memp-amem, ACTSIZE );
  173.         fprintf( foutput, "%d/%d distinct lookahead sets\n", nlset, LSETSIZE );
  174.         fprintf( foutput, "%d extra closures\n", zzclose - 2*nstate );
  175.         fprintf( foutput, "%d shift entries, %d exceptions\n", zzacent, zzexcp );
  176.         fprintf( foutput, "%d goto entries\n", zzgoent );
  177.         fprintf( foutput, "%d entries saved by goto default\n", zzgobest );
  178.         }
  179.     if( zzsrconf!=0 || zzrrconf!=0 ){
  180.           fprintf( stdout,"\nconflicts: ");
  181.           if( zzsrconf )fprintf( stdout, "%d shift/reduce" , zzsrconf );
  182.           if( zzsrconf && zzrrconf )fprintf( stdout, ", " );
  183.           if( zzrrconf )fprintf( stdout, "%d reduce/reduce" , zzrrconf );
  184.           fprintf( stdout, "\n" );
  185.           }
  186.  
  187.     fclose( ftemp );
  188.     if( fdefine != NULL ) fclose( fdefine );
  189.     }
  190.  
  191. /* VARARGS1 */
  192. error(s,a1) char *s; { /* write out error comment */
  193.     
  194.     ++nerrors;
  195.     fprintf( stderr, "\n fatal error: ");
  196.     fprintf( stderr, s,a1);
  197.     fprintf( stderr, ", line %d\n", lineno );
  198.     if( !fatfl ) return;
  199.     summary();
  200.     exit(1);
  201.     }
  202.  
  203. aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */
  204.     int i;
  205.     for( i=0; i<n; ++i ) v[i] = c;
  206.     }
  207.  
  208. setunion( a, b ) register *a, *b; {
  209.     /* set a to the union of a and b */
  210.     /* return 1 if b is not a subset of a, 0 otherwise */
  211.     register i, x, sub;
  212.  
  213.     sub = 0;
  214.     SETLOOP(i){
  215.         *a = (x = *a)|*b++;
  216.         if( *a++ != x ) sub = 1;
  217.         }
  218.     return( sub );
  219.     }
  220.  
  221. prlook( p ) struct looksets *p;{
  222.     register j, *pp;
  223.     pp = p->lset;
  224.     if( pp == 0 ) fprintf( foutput, "\tNULL");
  225.     else {
  226.         fprintf( foutput, " { " );
  227.         TLOOP(j) {
  228.             if( BIT(pp,j) ) fprintf( foutput,  "%s ", symnam(j) );
  229.             }
  230.         fprintf( foutput,  "}" );
  231.         }
  232.     }
  233.  
  234. cpres(){ /* compute an array with the beginnings of  productions yielding given nonterminals
  235.     The array pres points to these lists */
  236.     /* the array pyield has the lists: the total size is only NPROD+1 */
  237.     register **pmem;
  238.     register c, j, i;
  239.     static int * pyield[NPROD];
  240.  
  241.     pmem = pyield;
  242.  
  243.     NTLOOP(i){
  244.         c = i+NTBASE;
  245.         pres[i] = pmem;
  246.         fatfl = 0;  /* make undefined  symbols  nonfatal */
  247.         PLOOP(0,j){
  248.             if (*prdptr[j] == c) *pmem++ =  prdptr[j]+1;
  249.             }
  250.         if(pres[i] == pmem){
  251.             error("nonterminal %s not defined!", nontrst[i].name);
  252.             }
  253.         }
  254.     pres[i] = pmem;
  255.     fatfl = 1;
  256.     if( nerrors ){
  257.         summary();
  258.         exit(1);
  259.         }
  260.     if( pmem != &pyield[nprod] ) error( "internal Yacc error: pyield %d", pmem-&pyield[nprod] );
  261.     }
  262.  
  263. int indebug = 0;
  264. cpfir() {
  265.     /* compute an array with the first of nonterminals */
  266.     register *p, **s, i, **t, ch, changes;
  267.  
  268.     zzcwp = &wsets[nnonter];
  269.     NTLOOP(i){
  270.         aryfil( wsets[i].ws.lset, tbitset, 0 );
  271.         t = pres[i+1];
  272.         for( s=pres[i]; s<t; ++s ){ /* initially fill the sets */
  273.             for( p = *s; (ch = *p) > 0 ; ++p ) {
  274.                 if( ch < NTBASE ) {
  275.                     SETBIT( wsets[i].ws.lset, ch );
  276.                     break;
  277.                     }
  278.                 else if( !pempty[ch-NTBASE] ) break;
  279.                 }
  280.             }
  281.         }
  282.  
  283.     /* now, reflect transitivity */
  284.  
  285.     changes = 1;
  286.     while( changes ){
  287.         changes = 0;
  288.         NTLOOP(i){
  289.             t = pres[i+1];
  290.             for( s=pres[i]; s<t; ++s ){
  291.                 for( p = *s; ( ch = (*p-NTBASE) ) >= 0; ++p ) {
  292.                     changes |= setunion( wsets[i].ws.lset, wsets[ch].ws.lset );
  293.                     if( !pempty[ch] ) break;
  294.                     }
  295.                 }
  296.             }
  297.         }
  298.  
  299.     NTLOOP(i) pfirst[i] = flset( &wsets[i].ws );
  300.     if( !indebug ) return;
  301.     if( (foutput!=NULL) ){
  302.         NTLOOP(i) {
  303.             fprintf( foutput,  "\n%s: ", nontrst[i].name );
  304.             prlook( pfirst[i] );
  305.             fprintf( foutput,  " %d\n", pempty[i] );
  306.             }
  307.         }
  308.     }
  309.  
  310. state(c){ /* sorts last state,and sees if it equals earlier ones. returns state number */
  311.     int size1,size2;
  312.     register i;
  313.     struct item *p1, *p2, *k, *l, *q1, *q2;
  314.     p1 = pstate[nstate];
  315.     p2 = pstate[nstate+1];
  316.     if(p1==p2) return(0); /* null state */
  317.     /* sort the items */
  318.     for(k=p2-1;k>p1;k--) {    /* make k the biggest */
  319.         for(l=k-1;l>=p1;--l)if( l->pitem > k->pitem ){
  320.             int *s;
  321.             struct looksets *ss;
  322.             s = k->pitem;
  323.             k->pitem = l->pitem;
  324.             l->pitem = s;
  325.             ss = k->look;
  326.             k->look = l->look;
  327.             l->look = ss;
  328.             }
  329.         }
  330.     size1 = p2 - p1; /* size of state */
  331.  
  332.     for( i= (c>=NTBASE)?ntstates[c-NTBASE]:tstates[c]; i != 0; i = mstates[i] ) {
  333.         /* get ith state */
  334.         q1 = pstate[i];
  335.         q2 = pstate[i+1];
  336.         size2 = q2 - q1;
  337.         if (size1 != size2) continue;
  338.         k=p1;
  339.         for(l=q1;l<q2;l++) {
  340.             if( l->pitem != k->pitem ) break;
  341.             ++k;
  342.             }
  343.         if (l != q2) continue;
  344.         /* found it */
  345.         pstate[nstate+1] = pstate[nstate]; /* delete last state */
  346.         /* fix up lookaheads */
  347.         if( nolook ) return(i);
  348.         for( l=q1,k=p1; l<q2; ++l,++k ){
  349.             int s;
  350.             SETLOOP(s) clset.lset[s] = l->look->lset[s];
  351.             if( setunion( clset.lset, k->look->lset ) ) {
  352.                 tystate[i] = MUSTDO;
  353.                 /* register the new set */
  354.                 l->look = flset( &clset );
  355.                 }
  356.             }
  357.         return (i);
  358.         }
  359.     /* state is new */
  360.     if( nolook ) error( "yacc state/nolook error" );
  361.     pstate[nstate+2] = p2;
  362.     if(nstate+1 >= NSTATES) error("too many states" );
  363.     if( c >= NTBASE ){
  364.         mstates[ nstate ] = ntstates[ c-NTBASE ];
  365.         ntstates[ c-NTBASE ] = nstate;
  366.         }
  367.     else {
  368.         mstates[ nstate ] = tstates[ c ];
  369.         tstates[ c ] = nstate;
  370.         }
  371.     tystate[nstate]=MUSTDO;
  372.     return(nstate++);
  373.     }
  374.  
  375. int pidebug = 0; /* debugging flag for putitem */
  376. putitem( ptr, lptr )  int *ptr;  struct looksets *lptr; {
  377.     register struct item *j;
  378.  
  379.     if( pidebug && (foutput!=NULL) ) {
  380.         fprintf( foutput, "putitem(%s), state %d\n", writem(ptr), nstate );
  381.         }
  382.     j = pstate[nstate+1];
  383.     j->pitem = ptr;
  384.     if( !nolook ) j->look = flset( lptr );
  385.     pstate[nstate+1] = ++j;
  386.     if( (int *)j > zzmemsz ){
  387.         zzmemsz = (int *)j;
  388.         if( zzmemsz >=  &mem0[MEMSIZE] ) error( "out of state space" );
  389.         }
  390.     }
  391.  
  392. cempty(){ /* mark nonterminals which derive the empty string */
  393.     /* also, look for nonterminals which don't derive any token strings */
  394.  
  395. #define EMPTY 1
  396. #define WHOKNOWS 0
  397. #define OK 1
  398.  
  399.     register i, *p;
  400.  
  401.     /* first, use the array pempty to detect productions that can never be reduced */
  402.     /* set pempty to WHONOWS */
  403.     aryfil( pempty, nnonter+1, WHOKNOWS );
  404.  
  405.     /* now, look at productions, marking nonterminals which derive something */
  406.  
  407.     more:
  408.     PLOOP(0,i){
  409.         if( pempty[ *prdptr[i] - NTBASE ] ) continue;
  410.         for( p=prdptr[i]+1; *p>=0; ++p ){
  411.             if( *p>=NTBASE && pempty[ *p-NTBASE ] == WHOKNOWS ) break;
  412.             }
  413.         if( *p < 0 ){ /* production can be derived */
  414.             pempty[ *prdptr[i]-NTBASE ] = OK;
  415.             goto more;
  416.             }
  417.         }
  418.     }
  419.  
  420.     /* now, look at the nonterminals, to see if they are all OK */
  421.  
  422.     NTLOOP(i){
  423.         /* the added production rises or falls as the start symbol ... */
  424.         if( i == 0 ) continue;
  425.         if( pempty[ i ] != OK ) {
  426.             fatfl = 0;
  427.             error( "nonterminal %s never derives any token string", nontrst[i].name );
  428.             }
  429.         }
  430.  
  431.     if( nerrors ){
  432.         summary();
  433.         exit(1);
  434.         }
  435.     /* now, compute the pempty array, to see which nonterminals derive the empty string */
  436.  
  437.     /* set pempty to WHOKNOWS */
  438.  
  439.     aryfil( pempty, nnonter+1, WHOKNOWS );
  440.  
  441.     /* loop as long as we keep finding empty nonterminals */
  442.  
  443. again:
  444.     PLOOP(1,i){
  445.         if( pempty[ *prdptr[i]-NTBASE ]==WHOKNOWS ){ /* not known to be empty */
  446.             for( p=prdptr[i]+1; *p>=NTBASE && pempty[*p-NTBASE]==EMPTY ; ++p ) ;
  447.             if( *p < 0 ){ /* we have a nontrivially empty nonterminal */
  448.                 pempty[*prdptr[i]-NTBASE] = EMPTY;
  449.                 goto again; /* got one ... try for another */
  450.                 }
  451.             }
  452.         }
  453.  
  454.  
  455. int gsdebug = 0;
  456. stagen(){ /* generate the states */
  457.  
  458.     int i, j;
  459.     register c;
  460.     register struct wset *p, *q;
  461.  
  462.     /* initialize */
  463.  
  464.     nstate = 0;
  465.     /* THIS IS FUNNY from the standpoint of portability */
  466.     /* it represents the magic moment when the mem0 array, which has
  467.     /* been holding the productions, starts to hold item pointers, of a
  468.     /* different type... */
  469.     /* someday, alloc should be used to allocate all this stuff... for now, we
  470.     /* accept that if pointers don't fit in integers, there is a problem... */
  471.  
  472.     pstate[0] = pstate[1] = (struct item *)mem;
  473.     aryfil( clset.lset, tbitset, 0 );
  474.     putitem( prdptr[0]+1, &clset );
  475.     tystate[0] = MUSTDO;
  476.     nstate = 1;
  477.     pstate[2] = pstate[1];
  478.  
  479.     aryfil( amem, ACTSIZE, 0 );
  480.  
  481.     /* now, the main state generation loop */
  482.  
  483.     more:
  484.     SLOOP(i){
  485.         if( tystate[i] != MUSTDO ) continue;
  486.         tystate[i] = DONE;
  487.         aryfil( temp1, nnonter+1, 0 );
  488.         /* take state i, close it, and do gotos */
  489.         closure(i);
  490.         WSLOOP(wsets,p){ /* generate goto's */
  491.             if( p->flag ) continue;
  492.             p->flag = 1;
  493.             c = *(p->pitem);
  494.             if( c <= 1 ) {
  495.                 if( pstate[i+1]-pstate[i] <= p-wsets ) tystate[i] = MUSTLOOKAHEAD;
  496.                 continue;
  497.                 }
  498.             /* do a goto on c */
  499.             WSLOOP(p,q){
  500.                 if( c == *(q->pitem) ){ /* this item contributes to the goto */
  501.                     putitem( q->pitem + 1, &q->ws );
  502.                     q->flag = 1;
  503.                     }
  504.                 }
  505.             if( c < NTBASE ) {
  506.                 state(c);  /* register new state */
  507.                 }
  508.             else {
  509.                 temp1[c-NTBASE] = state(c);
  510.                 }
  511.             }
  512.         if( gsdebug && (foutput!=NULL) ){
  513.             fprintf( foutput,  "%d: ", i );
  514.             NTLOOP(j) {
  515.                 if( temp1[j] ) fprintf( foutput,  "%s %d, ", nontrst[j].name, temp1[j] );
  516.                 }
  517.             fprintf( foutput, "\n");
  518.             }
  519.         indgo[i] = apack( &temp1[1], nnonter-1 ) - 1;
  520.         goto more; /* we have done one goto; do some more */
  521.         }
  522.     /* no more to do... stop */
  523.     }
  524.  
  525. int cldebug = 0; /* debugging flag for closure */
  526. closure(i){ /* generate the closure of state i */
  527.  
  528.     int c, ch, work, k;
  529.     register struct wset *u, *v;
  530.     int *pi;
  531.     int **s, **t;
  532.     struct item *q;
  533.     register struct item *p;
  534.  
  535.     ++zzclose;
  536.  
  537.     /* first, copy kernel of state i to wsets */
  538.  
  539.     cwp = wsets;
  540.     ITMLOOP(i,p,q){
  541.         cwp->pitem = p->pitem;
  542.         cwp->flag = 1;    /* this item must get closed */
  543.         SETLOOP(k) cwp->ws.lset[k] = p->look->lset[k];
  544.         WSBUMP(cwp);
  545.         }
  546.  
  547.     /* now, go through the loop, closing each item */
  548.  
  549.     work = 1;
  550.     while( work ){
  551.         work = 0;
  552.         WSLOOP(wsets,u){
  553.     
  554.             if( u->flag == 0 ) continue;
  555.             c = *(u->pitem);  /* dot is before c */
  556.     
  557.             if( c < NTBASE ){
  558.                 u->flag = 0;
  559.                 continue;  /* only interesting case is where . is before nonterminal */
  560.                 }
  561.     
  562.             /* compute the lookahead */
  563.             aryfil( clset.lset, tbitset, 0 );
  564.  
  565.             /* find items involving c */
  566.  
  567.             WSLOOP(u,v){
  568.                 if( v->flag == 1 && *(pi=v->pitem) == c ){
  569.                     v->flag = 0;
  570.                     if( nolook ) continue;
  571.                     while( (ch= *++pi)>0 ){
  572.                         if( ch < NTBASE ){ /* terminal symbol */
  573.                             SETBIT( clset.lset, ch );
  574.                             break;
  575.                             }
  576.                         /* nonterminal symbol */
  577.                         setunion( clset.lset, pfirst[ch-NTBASE]->lset );
  578.                         if( !pempty[ch-NTBASE] ) break;
  579.                         }
  580.                     if( ch<=0 ) setunion( clset.lset, v->ws.lset );
  581.                     }
  582.                 }
  583.     
  584.             /*  now loop over productions derived from c */
  585.     
  586.             c -= NTBASE; /* c is now nonterminal number */
  587.     
  588.             t = pres[c+1];
  589.             for( s=pres[c]; s<t; ++s ){
  590.                 /* put these items into the closure */
  591.                 WSLOOP(wsets,v){ /* is the item there */
  592.                     if( v->pitem == *s ){ /* yes, it is there */
  593.                         if( nolook ) goto nexts;
  594.                         if( setunion( v->ws.lset, clset.lset ) ) v->flag = work = 1;
  595.                         goto nexts;
  596.                         }
  597.                     }
  598.     
  599.                 /*  not there; make a new entry */
  600.                 if( cwp-wsets+1 >= WSETSIZE ) error( "working set overflow" );
  601.                 cwp->pitem = *s;
  602.                 cwp->flag = 1;
  603.                 if( !nolook ){
  604.                     work = 1;
  605.                     SETLOOP(k) cwp->ws.lset[k] = clset.lset[k];
  606.                     }
  607.                 WSBUMP(cwp);
  608.     
  609.             nexts: ;
  610.                 }
  611.     
  612.             }
  613.         }
  614.  
  615.     /* have computed closure; flags are reset; return */
  616.  
  617.     if( cwp > zzcwp ) zzcwp = cwp;
  618.     if( cldebug && (foutput!=NULL) ){
  619.         fprintf( foutput, "\nState %d, nolook = %d\n", i, nolook );
  620.         WSLOOP(wsets,u){
  621.             if( u->flag ) fprintf( foutput, "flag set!\n");
  622.             u->flag = 0;
  623.             fprintf( foutput, "\t%s", writem(u->pitem));
  624.             prlook( &u->ws );
  625.             fprintf( foutput,  "\n" );
  626.             }
  627.         }
  628.     }
  629.  
  630. struct looksets *flset( p )   struct looksets *p; {
  631.     /* decide if the lookahead set pointed to by p is known */
  632.     /* return pointer to a perminent location for the set */
  633.  
  634.     register struct looksets *q;
  635.     int j, *w;
  636.     register *u, *v;
  637.  
  638.     for( q = &lkst[nlset]; q-- > lkst; ){
  639.         u = p->lset;
  640.         v = q->lset;
  641.         w = & v[tbitset];
  642.         while( v<w) if( *u++ != *v++ ) goto more;
  643.         /* we have matched */
  644.         return( q );
  645.         more: ;
  646.         }
  647.     /* add a new one */
  648.     q = &lkst[nlset++];
  649.     if( nlset >= LSETSIZE )error("too many lookahead sets" );
  650.     SETLOOP(j){
  651.         q->lset[j] = p->lset[j];
  652.         }
  653.     return( q );
  654.     }
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.